{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 机器学习练习-决策树\n",
    "\n",
    "实验要求：1，请将本实验中两处代码不完整的地方补充完整：2，如果出现graphviz问题，请尝试解决；3，对照本章ppt和本实验代码，理解决策树原理。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1．分类决策树模型是表示基于特征对实例进行分类的树形结构。决策树可以转换成一个**if-then**规则的集合，也可以看作是定义在特征空间划分上的类的条件概率分布。\n",
    "\n",
    "2．决策树学习旨在构建一个与训练数据拟合很好，并且复杂度小的决策树。因为从可能的决策树中直接选取最优决策树是NP完全问题。现实中采用启发式方法学习次优的决策树。\n",
    "\n",
    "决策树学习算法包括3部分：特征选择、树的生成和树的剪枝。常用的算法有ID3、\n",
    "C4.5和CART。\n",
    "\n",
    "3．特征选择的目的在于选取对训练数据能够分类的特征。特征选择的关键是其准则。常用的准则如下：\n",
    "\n",
    "（1）样本集合$D$对特征$A$的信息增益（ID3）\n",
    "\n",
    "\n",
    "$$g(D, A)=H(D)-H(D|A)$$\n",
    "\n",
    "$$H(D)=-\\sum_{k=1}^{K} \\frac{\\left|C_{k}\\right|}{|D|} \\log _{2} \\frac{\\left|C_{k}\\right|}{|D|}$$\n",
    "\n",
    "$$H(D | A)=\\sum_{i=1}^{n} \\frac{\\left|D_{i}\\right|}{|D|} H\\left(D_{i}\\right)$$\n",
    "\n",
    "其中，$H(D)$是数据集$D$的熵，$H(D_i)$是数据集$D_i$的熵，$H(D|A)$是数据集$D$对特征$A$的条件熵。\t$D_i$是$D$中特征$A$取第$i$个值的样本子集，$C_k$是$D$中属于第$k$类的样本子集。$n$是特征$A$取 值的个数，$K$是类的个数。\n",
    "\n",
    "（2）样本集合$D$对特征$A$的信息增益比（C4.5）\n",
    "\n",
    "\n",
    "$$g_{R}(D, A)=\\frac{g(D, A)}{H(D)}$$\n",
    "\n",
    "\n",
    "其中，$g(D,A)$是信息增益，$H(D)$是数据集$D$的熵。\n",
    "\n",
    "（3）样本集合$D$的基尼指数（CART）\n",
    "\n",
    "$$\\operatorname{Gini}(D)=1-\\sum_{k=1}^{K}\\left(\\frac{\\left|C_{k}\\right|}{|D|}\\right)^{2}$$\n",
    "\n",
    "特征$A$条件下集合$D$的基尼指数：\n",
    "\n",
    " $$\\operatorname{Gini}(D, A)=\\frac{\\left|D_{1}\\right|}{|D|} \\operatorname{Gini}\\left(D_{1}\\right)+\\frac{\\left|D_{2}\\right|}{|D|} \\operatorname{Gini}\\left(D_{2}\\right)$$\n",
    " \n",
    "4．决策树的生成。通常使用信息增益最大、信息增益比最大或基尼指数最小作为特征选择的准则。决策树的生成往往通过计算信息增益或其他指标，从根结点开始，递归地产生决策树。这相当于用信息增益或其他准则不断地选取局部最优的特征，或将训练集分割为能够基本正确分类的子集。\n",
    "\n",
    "5．决策树的剪枝。由于生成的决策树存在过拟合问题，需要对它进行剪枝，以简化学到的决策树。决策树的剪枝，往往从已生成的树上剪掉一些叶结点或叶结点以上的子树，并将其父结点或根结点作为新的叶结点，从而简化生成的决策树。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import math\n",
    "from math import log"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 创建数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_data():\n",
    "    datasets = [['青年', '否', '否', '一般', '否'],\n",
    "               ['青年', '否', '否', '好', '否'],\n",
    "               ['青年', '是', '否', '好', '是'],\n",
    "               ['青年', '是', '是', '一般', '是'],\n",
    "               ['青年', '否', '否', '一般', '否'],\n",
    "               ['中年', '否', '否', '一般', '否'],\n",
    "               ['中年', '否', '否', '好', '否'],\n",
    "               ['中年', '是', '是', '好', '是'],\n",
    "               ['中年', '否', '是', '非常好', '是'],\n",
    "               ['中年', '否', '是', '非常好', '是'],\n",
    "               ['老年', '否', '是', '非常好', '是'],\n",
    "               ['老年', '否', '是', '好', '是'],\n",
    "               ['老年', '是', '否', '好', '是'],\n",
    "               ['老年', '是', '否', '非常好', '是'],\n",
    "               ['老年', '否', '否', '一般', '否'],\n",
    "               ]\n",
    "    labels = [u'年龄', u'有工作', u'有自己的房子', u'信贷情况', u'类别']\n",
    "    # 返回数据集和每个维度的名称\n",
    "    return datasets, labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "datasets, labels = create_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data = pd.DataFrame(datasets, columns=labels)\n",
    "#train_data =             (datasets, columns=labels) #请将本行代码补充完整"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>年龄</th>\n",
       "      <th>有工作</th>\n",
       "      <th>有自己的房子</th>\n",
       "      <th>信贷情况</th>\n",
       "      <th>类别</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>青年</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>一般</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>青年</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>好</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>青年</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>青年</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>一般</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>青年</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>一般</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>中年</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>一般</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>中年</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>好</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>中年</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>中年</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>非常好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>中年</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>非常好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>老年</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>非常好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>老年</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>老年</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>老年</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>非常好</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>老年</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>一般</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    年龄 有工作 有自己的房子 信贷情况 类别\n",
       "0   青年   否      否   一般  否\n",
       "1   青年   否      否    好  否\n",
       "2   青年   是      否    好  是\n",
       "3   青年   是      是   一般  是\n",
       "4   青年   否      否   一般  否\n",
       "5   中年   否      否   一般  否\n",
       "6   中年   否      否    好  否\n",
       "7   中年   是      是    好  是\n",
       "8   中年   否      是  非常好  是\n",
       "9   中年   否      是  非常好  是\n",
       "10  老年   否      是  非常好  是\n",
       "11  老年   否      是    好  是\n",
       "12  老年   是      否    好  是\n",
       "13  老年   是      否  非常好  是\n",
       "14  老年   否      否   一般  否"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 熵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算给定数据集的熵（信息熵）\n",
    "def calc_ent(datasets):\n",
    "    # 计算数据集的长度\n",
    "    data_length = len(datasets)\n",
    "    # 统计数据集中每个类别的出现次数\n",
    "    label_count = {}\n",
    "    for i in range(data_length):\n",
    "        # 获取每个样本的标签\n",
    "        label = datasets[i][-1]\n",
    "        # 如果该类别不在label_count中，则添加到label_count中\n",
    "        if label not in label_count:\n",
    "            label_count[label] = 0\n",
    "        # 统计该类别的出现次数\n",
    "        label_count[label] += 1\n",
    "    # 计算熵\n",
    "    ent = -sum([(p / data_length) * log(p / data_length, 2)\n",
    "                for p in label_count.values()])\n",
    "    return ent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 条件熵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算给定数据集在指定特征上的条件熵\n",
    "def cond_ent(datasets, axis=0):\n",
    "    # 计算数据集的长度\n",
    "    data_length = len(datasets)\n",
    "    # 使用字典feature_sets存储在指定特征上的不同取值对应的样本集合\n",
    "    feature_sets = {}\n",
    "    for i in range(data_length):\n",
    "        # 获取每个样本在指定特征上的取值\n",
    "        feature = datasets[i][axis]\n",
    "        # 如果该取值不在feature_sets中，则添加到feature_sets中\n",
    "        if feature not in feature_sets:\n",
    "            feature_sets[feature] = []\n",
    "        # 将该样本添加到对应取值的样本集合中\n",
    "        feature_sets[feature].append(datasets[i])\n",
    "    # 计算条件熵\n",
    "    cond_ent = sum([(len(p) / data_length) * calc_ent(p)\n",
    "                    for p in feature_sets.values()])\n",
    "    return cond_ent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9709505944546686"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "calc_ent(datasets)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 信息增益"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算信息增益\n",
    "def info_gain(ent, cond_ent):\n",
    "    # 信息增益等于熵减去条件熵\n",
    "    return ent - cond_ent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用信息增益选择最佳特征作为根节点特征进行决策树的训练\n",
    "def info_gain_train(datasets):\n",
    "    # 计算特征的数量\n",
    "    count = len(datasets[0]) - 1\n",
    "    # 计算整个数据集的熵\n",
    "    ent = calc_ent(datasets)\n",
    "    # 存储每个特征的信息增益\n",
    "    best_feature = []\n",
    "    for c in range(count):\n",
    "        # 计算每个特征的条件熵\n",
    "        c_info_gain = info_gain(ent, cond_ent(datasets, axis=c))\n",
    "        # 将特征及其对应的信息增益存入best_feature列表中\n",
    "        best_feature.append((c, c_info_gain))\n",
    "        # 输出每个特征的信息增益\n",
    "        print('特征({}) 的信息增益为： {:.3f}'.format(labels[c], c_info_gain))\n",
    "    # 找到信息增益最大的特征\n",
    "    best_ = max(best_feature, key=lambda x: x[-1])\n",
    "    # 返回信息增益最大的特征作为根节点特征\n",
    "    return '特征({})的信息增益最大，选择为根节点特征'.format(labels[best_[0]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特征(年龄) 的信息增益为： 0.083\n",
      "特征(有工作) 的信息增益为： 0.324\n",
      "特征(有自己的房子) 的信息增益为： 0.420\n",
      "特征(信贷情况) 的信息增益为： 0.363\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'特征(有自己的房子)的信息增益最大，选择为根节点特征'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "info_gain_train(np.array(datasets))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 利用ID3算法生成决策树"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义节点类 二叉树\n",
    "class Node:\n",
    "    def __init__(self, root=True, label=None, feature_name=None, feature=None):\n",
    "        self.root = root\n",
    "        self.label = label\n",
    "        self.feature_name = feature_name\n",
    "        self.feature = feature\n",
    "        self.tree = {}\n",
    "        self.result = {\n",
    "            'label:': self.label,\n",
    "            'feature': self.feature,\n",
    "            'tree': self.tree\n",
    "        }\n",
    "\n",
    "    def __repr__(self):\n",
    "        return '{}'.format(self.result)\n",
    "\n",
    "    def add_node(self, val, node):\n",
    "        self.tree[val] = node\n",
    "\n",
    "    def predict(self, features):\n",
    "        if self.root is True:\n",
    "            return self.label\n",
    "        return self.tree[features[self.feature]].predict(features)\n",
    "\n",
    "\n",
    "class DTree:\n",
    "    def __init__(self, epsilon=0.1):\n",
    "        self.epsilon = epsilon\n",
    "        self._tree = {}\n",
    "\n",
    "    # 熵\n",
    "    @staticmethod\n",
    "    def calc_ent(datasets):\n",
    "        data_length = len(datasets)\n",
    "        label_count = {}\n",
    "        for i in range(data_length):\n",
    "            label = datasets[i][-1]\n",
    "            if label not in label_count:\n",
    "                label_count[label] = 0\n",
    "            label_count[label] += 1\n",
    "        ent = -sum([(p / data_length) * log(p / data_length, 2)\n",
    "                    for p in label_count.values()])\n",
    "        return ent\n",
    "\n",
    "    # 经验条件熵\n",
    "    def cond_ent(self, datasets, axis=0):\n",
    "        data_length = len(datasets)\n",
    "        feature_sets = {}\n",
    "        for i in range(data_length):\n",
    "            feature = datasets[i][axis]\n",
    "            if feature not in feature_sets:\n",
    "                feature_sets[feature] = []\n",
    "            feature_sets[feature].append(datasets[i])\n",
    "        cond_ent = sum([(len(p) / data_length) * self.calc_ent(p)\n",
    "                        for p in feature_sets.values()])\n",
    "        return cond_ent\n",
    "\n",
    "    # 信息增益\n",
    "    @staticmethod\n",
    "    def info_gain(ent, cond_ent):\n",
    "        return ent - cond_ent\n",
    "\n",
    "    def info_gain_train(self, datasets):\n",
    "        count = len(datasets[0]) - 1\n",
    "        ent = self.calc_ent(datasets)\n",
    "        best_feature = []\n",
    "        for c in range(count):\n",
    "            c_info_gain = self.info_gain(ent, self.cond_ent(datasets, axis=c))\n",
    "            best_feature.append((c, c_info_gain))\n",
    "        # 比较大小\n",
    "        best_ = max(best_feature, key=lambda x: x[-1])\n",
    "        return best_\n",
    "\n",
    "    def train(self, train_data):\n",
    "        \"\"\"\n",
    "        input:数据集D(DataFrame格式)，特征集A，阈值eta\n",
    "        output:决策树T\n",
    "        \"\"\"\n",
    "        _, y_train, features = train_data.iloc[:, :\n",
    "                                               -1], train_data.iloc[:,\n",
    "                                                                    -1], train_data.columns[:\n",
    "                                                                                            -1]\n",
    "        # 1,若D中实例属于同一类Ck，则T为单节点树，并将类Ck作为结点的类标记，返回T\n",
    "        if len(y_train.value_counts()) == 1:\n",
    "            return Node(root=True, label=y_train.iloc[0])\n",
    "\n",
    "        # 2, 若A为空，则T为单节点树，将D中实例树最大的类Ck作为该节点的类标记，返回T\n",
    "        if len(features) == 0:\n",
    "            return Node(\n",
    "                root=True,\n",
    "                label=y_train.value_counts().sort_values(\n",
    "                    ascending=False).index[0])\n",
    "\n",
    "        # 3,计算最大信息增益 同5.1,Ag为信息增益最大的特征\n",
    "        max_feature, max_info_gain = self.info_gain_train(np.array(train_data))\n",
    "        max_feature_name = features[max_feature]\n",
    "\n",
    "        # 4,Ag的信息增益小于阈值eta,则置T为单节点树，并将D中是实例数最大的类Ck作为该节点的类标记，返回T\n",
    "        if max_info_gain < self.epsilon:\n",
    "            return Node(\n",
    "                root=True,\n",
    "                label=y_train.value_counts().sort_values(\n",
    "                    ascending=False).index[0])\n",
    "\n",
    "        # 5,构建Ag子集\n",
    "        node_tree = Node(\n",
    "            root=False, feature_name=max_feature_name, feature=max_feature)\n",
    "\n",
    "        feature_list = train_data[max_feature_name].value_counts().index\n",
    "        for f in feature_list:\n",
    "            sub_train_df = train_data.loc[train_data[max_feature_name] ==\n",
    "                                          f].drop([max_feature_name], axis=1)\n",
    "\n",
    "            # 6, 递归生成树\n",
    "            sub_tree = self.train(sub_train_df)\n",
    "            node_tree.add_node(f, sub_tree)\n",
    "\n",
    "        # pprint.pprint(node_tree.tree)\n",
    "        return node_tree\n",
    "\n",
    "    def fit(self, train_data):\n",
    "        self._tree = self.train(train_data)\n",
    "        return self._tree\n",
    "\n",
    "    def predict(self, X_test):\n",
    "        return self._tree.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "datasets, labels = create_data()\n",
    "data_df = pd.DataFrame(datasets, columns=labels)\n",
    "dt = DTree()\n",
    "tree = dt.fit(data_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'label:': None, 'feature': 2, 'tree': {'否': {'label:': None, 'feature': 1, 'tree': {'否': {'label:': '否', 'feature': None, 'tree': {}}, '是': {'label:': '是', 'feature': None, 'tree': {}}}}, '是': {'label:': '是', 'feature': None, 'tree': {}}}}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'否'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dt.predict(['老年', '否', '否', '一般'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scikit-learn实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split\n",
    "from collections import Counter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用Iris数据集，我们可以构建如下树："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# data\n",
    "def create_data():\n",
    "    iris =load_iris() #请将本行代码补充完整       \n",
    "    df = pd.DataFrame(iris.data, columns=iris.feature_names)\n",
    "    df['label'] = iris.target\n",
    "    df.columns = [\n",
    "        'sepal length', 'sepal width', 'petal length', 'petal width', 'label'\n",
    "    ]\n",
    "    data = np.array(df.iloc[:100, [0, 1, -1]])\n",
    "    # print(data)\n",
    "    return data[:, :2], data[:, -1],iris.feature_names[0:2]\n",
    "\n",
    "\n",
    "X, y,feature_name= create_data()\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 决策树分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9666666666666667"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.tree import export_graphviz\n",
    "import graphviz\n",
    "from sklearn import tree\n",
    "\n",
    "clf = DecisionTreeClassifier()\n",
    "clf.fit(X_train, y_train,)\n",
    "\n",
    "clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "graphviz_path=r'D:\\DOWNLOAD\\Graphviz\\bin'\n",
    "os.environ[\"PATH\"] += os.pathsep + graphviz_path"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一旦经过训练，就可以用 plot_tree函数绘制树："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Text(0.5555555555555556, 0.875, 'x[0] <= 5.45\\ngini = 0.5\\nsamples = 70\\nvalue = [36, 34]'),\n",
       " Text(0.3333333333333333, 0.625, 'x[1] <= 2.8\\ngini = 0.193\\nsamples = 37\\nvalue = [33, 4]'),\n",
       " Text(0.2222222222222222, 0.375, 'x[0] <= 4.7\\ngini = 0.32\\nsamples = 5\\nvalue = [1, 4]'),\n",
       " Text(0.1111111111111111, 0.125, 'gini = 0.0\\nsamples = 1\\nvalue = [1, 0]'),\n",
       " Text(0.3333333333333333, 0.125, 'gini = 0.0\\nsamples = 4\\nvalue = [0, 4]'),\n",
       " Text(0.4444444444444444, 0.375, 'gini = 0.0\\nsamples = 32\\nvalue = [32, 0]'),\n",
       " Text(0.7777777777777778, 0.625, 'x[1] <= 3.45\\ngini = 0.165\\nsamples = 33\\nvalue = [3, 30]'),\n",
       " Text(0.6666666666666666, 0.375, 'gini = 0.0\\nsamples = 30\\nvalue = [0, 30]'),\n",
       " Text(0.8888888888888888, 0.375, 'gini = 0.0\\nsamples = 3\\nvalue = [3, 0]')]"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tree.plot_tree(clf) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可以导出树"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "tree_pic = export_graphviz(clf, out_file=\"mytree.pdf\")\n",
    "with open('mytree.pdf') as f:\n",
    "    dot_graph = f.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 12.2.1 (20241206.2353)\n",
       " -->\n",
       "<!-- Title: Tree Pages: 1 -->\n",
       "<svg width=\"510pt\" height=\"384pt\"\n",
       " viewBox=\"0.00 0.00 510.00 384.25\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 380.25)\">\n",
       "<title>Tree</title>\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-380.25 506,-380.25 506,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"333.5,-376.25 224.5,-376.25 224.5,-305.25 333.5,-305.25 333.5,-376.25\"/>\n",
       "<text text-anchor=\"middle\" x=\"279\" y=\"-358.95\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">x[0] &lt;= 5.45</text>\n",
       "<text text-anchor=\"middle\" x=\"279\" y=\"-343.2\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.5</text>\n",
       "<text text-anchor=\"middle\" x=\"279\" y=\"-327.45\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 70</text>\n",
       "<text text-anchor=\"middle\" x=\"279\" y=\"-311.7\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [36, 34]</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"269.75,-269.25 168.25,-269.25 168.25,-198.25 269.75,-198.25 269.75,-269.25\"/>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-251.95\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">x[1] &lt;= 2.8</text>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-236.2\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.193</text>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-220.45\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 37</text>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-204.7\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [33, 4]</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M259.02,-304.79C254.37,-296.64 249.35,-287.86 244.49,-279.36\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"247.64,-277.82 239.64,-270.87 241.57,-281.29 247.64,-277.82\"/>\n",
       "<text text-anchor=\"middle\" x=\"232.31\" y=\"-288.25\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">True</text>\n",
       "</g>\n",
       "<!-- 6 -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>6</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"389.75,-269.25 288.25,-269.25 288.25,-198.25 389.75,-198.25 389.75,-269.25\"/>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-251.95\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">x[1] &lt;= 3.45</text>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-236.2\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.165</text>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-220.45\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 33</text>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-204.7\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [3, 30]</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;6 -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>0&#45;&gt;6</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M298.98,-304.79C303.63,-296.64 308.65,-287.86 313.51,-279.36\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"316.43,-281.29 318.36,-270.87 310.36,-277.82 316.43,-281.29\"/>\n",
       "<text text-anchor=\"middle\" x=\"325.69\" y=\"-288.25\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">False</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"150,-162.25 56,-162.25 56,-91.25 150,-91.25 150,-162.25\"/>\n",
       "<text text-anchor=\"middle\" x=\"103\" y=\"-144.95\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">x[0] &lt;= 4.7</text>\n",
       "<text text-anchor=\"middle\" x=\"103\" y=\"-129.2\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.32</text>\n",
       "<text text-anchor=\"middle\" x=\"103\" y=\"-113.45\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 5</text>\n",
       "<text text-anchor=\"middle\" x=\"103\" y=\"-97.7\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [1, 4]</text>\n",
       "</g>\n",
       "<!-- 1&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>1&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M180.37,-197.79C170.59,-188.93 159.98,-179.32 149.84,-170.14\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"152.34,-167.69 142.58,-163.58 147.64,-172.88 152.34,-167.69\"/>\n",
       "</g>\n",
       "<!-- 5 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>5</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"269.75,-154.38 168.25,-154.38 168.25,-99.12 269.75,-99.12 269.75,-154.38\"/>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-137.07\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.0</text>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-121.33\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 32</text>\n",
       "<text text-anchor=\"middle\" x=\"219\" y=\"-105.58\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [32, 0]</text>\n",
       "</g>\n",
       "<!-- 1&#45;&gt;5 -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>1&#45;&gt;5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M219,-197.79C219,-187.56 219,-176.32 219,-165.91\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"222.5,-166.1 219,-156.1 215.5,-166.1 222.5,-166.1\"/>\n",
       "</g>\n",
       "<!-- 3 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>3</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"94,-55.25 0,-55.25 0,0 94,0 94,-55.25\"/>\n",
       "<text text-anchor=\"middle\" x=\"47\" y=\"-37.95\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.0</text>\n",
       "<text text-anchor=\"middle\" x=\"47\" y=\"-22.2\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 1</text>\n",
       "<text text-anchor=\"middle\" x=\"47\" y=\"-6.45\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [1, 0]</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;3 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>2&#45;&gt;3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M82.94,-90.96C78.17,-82.68 73.06,-73.81 68.23,-65.45\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"71.31,-63.78 63.28,-56.87 65.25,-67.28 71.31,-63.78\"/>\n",
       "</g>\n",
       "<!-- 4 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>4</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"206,-55.25 112,-55.25 112,0 206,0 206,-55.25\"/>\n",
       "<text text-anchor=\"middle\" x=\"159\" y=\"-37.95\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.0</text>\n",
       "<text text-anchor=\"middle\" x=\"159\" y=\"-22.2\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 4</text>\n",
       "<text text-anchor=\"middle\" x=\"159\" y=\"-6.45\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [0, 4]</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;4 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>2&#45;&gt;4</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M123.06,-90.96C127.83,-82.68 132.94,-73.81 137.77,-65.45\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"140.75,-67.28 142.72,-56.87 134.69,-63.78 140.75,-67.28\"/>\n",
       "</g>\n",
       "<!-- 7 -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>7</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"389.75,-154.38 288.25,-154.38 288.25,-99.12 389.75,-99.12 389.75,-154.38\"/>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-137.07\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.0</text>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-121.33\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 30</text>\n",
       "<text text-anchor=\"middle\" x=\"339\" y=\"-105.58\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [0, 30]</text>\n",
       "</g>\n",
       "<!-- 6&#45;&gt;7 -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>6&#45;&gt;7</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M339,-197.79C339,-187.56 339,-176.32 339,-165.91\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"342.5,-166.1 339,-156.1 335.5,-166.1 342.5,-166.1\"/>\n",
       "</g>\n",
       "<!-- 8 -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>8</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"502,-154.38 408,-154.38 408,-99.12 502,-99.12 502,-154.38\"/>\n",
       "<text text-anchor=\"middle\" x=\"455\" y=\"-137.07\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">gini = 0.0</text>\n",
       "<text text-anchor=\"middle\" x=\"455\" y=\"-121.33\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">samples = 3</text>\n",
       "<text text-anchor=\"middle\" x=\"455\" y=\"-105.58\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">value = [3, 0]</text>\n",
       "</g>\n",
       "<!-- 6&#45;&gt;8 -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>6&#45;&gt;8</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M377.63,-197.79C390.26,-186.35 404.29,-173.65 416.89,-162.25\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"419.16,-164.91 424.23,-155.61 414.46,-159.72 419.16,-164.91\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x1b6bd06abf0>"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graphviz.Source(dot_graph)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 决策树回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from sklearn.tree import DecisionTreeRegressor\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a random dataset\n",
    "rng = np.random.RandomState(1)\n",
    "X = np.sort(5 * rng.rand(80, 1), axis=0)\n",
    "y = np.sin(X).ravel()\n",
    "y[::5] += 3 * (0.5 - rng.rand(16))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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w6EMGjQIx48fx9GjR7U/vXr1wsSJE3H06FEGQhZUUVGBkydPIigoyOqvzcyQDcyePRuJiYno1asXYmNjsWLFCuTm5mLq1Km2bppDKS0tRXZ2tvb22bNncfToUbRq1QqhoaE2bJljmT59Or766it899138Pb21mY9fXx84OnpaePWOY7XXnsNcXFxCAkJwY0bN7Bu3Trs3r0b27Zts3XTHIq3t3ed/m7NmzeHn58f+8GZ2csvv4wHH3wQoaGhyMvLw7vvvouSkhI88cQTVm8LgyEbGD9+PPLz8/H222/j8uXL6Ny5M1JTUxEWFmbrpjmUQ4cOYeDAgdrbmhr0E088gaSkJBu1yvFopogYMGCAaPuqVaswefJk6zfIQV29ehWJiYm4fPkyfHx80LVrV2zbtg1DhgyxddOImuTvv//GhAkTcP36dbRu3Rp9+vRBRkaGTa6FnGeIiIiInBr7DBEREZFTYzBERERETo3BEBERETk1BkNERETk1BgMERERkVNjMEREREROjcEQEREROTUGQ0TksAYMGICZM2fauhlEZOcYDBERAdi9ezdkMhmKiops3RQisjIGQ0REROTUGAwRkUMoKyvD448/Di8vLwQFBeGDDz4Q3Z+cnIxevXrB29sbbdq0QUJCAvLy8gAA586d065j5+vrC5lMpl1Xbdu2bbjvvvvQsmVL+Pn5YeTIkcjJybHqeyMiy2IwREQO4ZVXXsGuXbuwadMmbN++Hbt378bhw4e191dWVuKdd97BH3/8gc2bN+Ps2bPagCckJATffPMNAOD06dO4fPkyli5dCkAdZM2ePRsHDx7Ejz/+CLlcjjFjxkClUln9PRKRZXChViKSvNLSUvj5+WHNmjUYP348AKCgoADBwcF49tlnsWTJkjqPOXjwIO655x7cuHEDXl5e2L17NwYOHIjCwkK0bNmy3te6du0aAgICcPz4cXTu3NlC74iIrImZISKSvJycHFRWViI2Nla7rVWrVoiJidHePnLkCEaPHo2wsDB4e3tjwIABAIDc3FyDz52QkID27dujRYsWCA8PN+pxRCQdDIaISPIMJbjLysowdOhQeHl5ITk5GQcPHsSmTZsAqMtnDXnwwQeRn5+Pzz//HPv378f+/fuNehwRSQeDISKSvMjISLi6uiIjI0O7rbCwEJmZmQCAU6dO4fr163j//fdx//33o0OHDtrO0xpubm4AAKVSqd2Wn5+PkydP4vXXX8egQYPQsWNHFBYWWuEdEZE1MRgiIsnz8vLC008/jVdeeQU//vgj/vzzT0yePBlyufoUFxoaCjc3N3z00Uc4c+YMvv/+e7zzzjui5wgLC4NMJsOWLVtw7do1lJaWwtfXF35+flixYgWys7Px008/Yfbs2bZ4i0RkQQyGiMghLFq0CP369cOoUaMwePBg3HfffejZsycAoHXr1khKSsLGjRtx55134v3338fixYtFj7/jjjswf/58vPrqqwgMDMTzzz8PuVyOdevW4fDhw+jcuTNmzZqFRYsW2eLtEZEFcTQZEREROTVmhoiIiMipMRgiIiIip8ZgiIiIiJwagyEiIiJyagyGiIiIyKkxGCIiIiKnxmCIiIiInBqDISIiInJqDIaIiIjIqTEYIiIiIqfGYIiIiIicGoMhIiIicmr/D8VSyYayeY0JAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Fit regression model\n",
    "regr_1 = DecisionTreeRegressor(max_depth=2)\n",
    "regr_2 = DecisionTreeRegressor(max_depth=5)\n",
    "regr_1.fit(X, y)\n",
    "regr_2.fit(X, y)\n",
    "\n",
    "# Predict\n",
    "X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]\n",
    "y_1 = regr_1.predict(X_test)\n",
    "y_2 = regr_2.predict(X_test)\n",
    "\n",
    "# Plot the results\n",
    "plt.figure()\n",
    "plt.scatter(X, y, s=20, edgecolor=\"black\", c=\"darkorange\", label=\"data\")\n",
    "plt.plot(X_test, y_1, color=\"cornflowerblue\", label=\"max_depth=2\", linewidth=2)\n",
    "plt.plot(X_test, y_2, color=\"yellowgreen\", label=\"max_depth=5\", linewidth=2)\n",
    "plt.xlabel(\"data\")\n",
    "plt.ylabel(\"target\")\n",
    "plt.title(\"Decision Tree Regression\")\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scikit-learn 的决策树参数"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "DecisionTreeClassifier(criterion=\"gini\",\n",
    "                 splitter=\"best\",\n",
    "                 max_depth=None,\n",
    "                 min_samples_split=2,\n",
    "                 min_samples_leaf=1,\n",
    "                 min_weight_fraction_leaf=0.,\n",
    "                 max_features=None,\n",
    "                 random_state=None,\n",
    "                 max_leaf_nodes=None,\n",
    "                 min_impurity_decrease=0.,\n",
    "                 min_impurity_split=None,\n",
    "                 class_weight=None,\n",
    "                 presort=False)\n",
    "\n",
    "参数含义：\n",
    "1.criterion:string, optional (default=\"gini\")\n",
    "            (1).criterion='gini',分裂节点时评价准则是Gini指数。\n",
    "            (2).criterion='entropy',分裂节点时的评价指标是信息增益。\n",
    "2.max_depth:int or None, optional (default=None)。指定树的最大深度。\n",
    "            如果为None，表示树的深度不限。直到所有的叶子节点都是纯净的，即叶子节点\n",
    "            中所有的样本点都属于同一个类别。或者每个叶子节点包含的样本数小于min_samples_split。\n",
    "3.splitter:string, optional (default=\"best\")。指定分裂节点时的策略。\n",
    "           (1).splitter='best',表示选择最优的分裂策略。\n",
    "           (2).splitter='random',表示选择最好的随机切分策略。\n",
    "4.min_samples_split:int, float, optional (default=2)。表示分裂一个内部节点需要的做少样本数。\n",
    "           (1).如果为整数，则min_samples_split就是最少样本数。\n",
    "           (2).如果为浮点数(0到1之间)，则每次分裂最少样本数为ceil(min_samples_split * n_samples)\n",
    "5.min_samples_leaf: int, float, optional (default=1)。指定每个叶子节点需要的最少样本数。\n",
    "           (1).如果为整数，则min_samples_split就是最少样本数。\n",
    "           (2).如果为浮点数(0到1之间)，则每个叶子节点最少样本数为ceil(min_samples_leaf * n_samples)\n",
    "6.min_weight_fraction_leaf:float, optional (default=0.)\n",
    "           指定叶子节点中样本的最小权重。\n",
    "7.max_features:int, float, string or None, optional (default=None).\n",
    "           搜寻最佳划分的时候考虑的特征数量。\n",
    "           (1).如果为整数，每次分裂只考虑max_features个特征。\n",
    "           (2).如果为浮点数(0到1之间)，每次切分只考虑int(max_features * n_features)个特征。\n",
    "           (3).如果为'auto'或者'sqrt',则每次切分只考虑sqrt(n_features)个特征\n",
    "           (4).如果为'log2',则每次切分只考虑log2(n_features)个特征。\n",
    "           (5).如果为None,则每次切分考虑n_features个特征。\n",
    "           (6).如果已经考虑了max_features个特征，但还是没有找到一个有效的切分，那么还会继续寻找\n",
    "           下一个特征，直到找到一个有效的切分为止。\n",
    "8.random_state:int, RandomState instance or None, optional (default=None)\n",
    "           (1).如果为整数，则它指定了随机数生成器的种子。\n",
    "           (2).如果为RandomState实例，则指定了随机数生成器。\n",
    "           (3).如果为None，则使用默认的随机数生成器。\n",
    "9.max_leaf_nodes: int or None, optional (default=None)。指定了叶子节点的最大数量。\n",
    "           (1).如果为None,叶子节点数量不限。\n",
    "           (2).如果为整数，则max_depth被忽略。\n",
    "10.min_impurity_decrease:float, optional (default=0.)\n",
    "         如果节点的分裂导致不纯度的减少(分裂后样本比分裂前更加纯净)大于或等于min_impurity_decrease，则分裂该节点。\n",
    "         加权不纯度的减少量计算公式为：\n",
    "         min_impurity_decrease=N_t / N * (impurity - N_t_R / N_t * right_impurity\n",
    "                            - N_t_L / N_t * left_impurity)\n",
    "         其中N是样本的总数，N_t是当前节点的样本数，N_t_L是分裂后左子节点的样本数，\n",
    "         N_t_R是分裂后右子节点的样本数。impurity指当前节点的基尼指数，right_impurity指\n",
    "         分裂后右子节点的基尼指数。left_impurity指分裂后左子节点的基尼指数。\n",
    "11.min_impurity_split:float\n",
    "         树生长过程中早停止的阈值。如果当前节点的不纯度高于阈值，节点将分裂，否则它是叶子节点。\n",
    "         这个参数已经被弃用。用min_impurity_decrease代替了min_impurity_split。\n",
    "12.class_weight:dict, list of dicts, \"balanced\" or None, default=None\n",
    "         类别权重的形式为{class_label: weight}\n",
    "         (1).如果没有给出每个类别的权重，则每个类别的权重都为1。\n",
    "         (2).如果class_weight='balanced'，则分类的权重与样本中每个类别出现的频率成反比。\n",
    "         计算公式为：n_samples / (n_classes * np.bincount(y))\n",
    "         (3).如果sample_weight提供了样本权重(由fit方法提供)，则这些权重都会乘以sample_weight。\n",
    "13.presort:bool, optional (default=False)\n",
    "        指定是否需要提前排序数据从而加速训练中寻找最优切分的过程。设置为True时，对于大数据集\n",
    "        会减慢总体的训练过程；但是对于一个小数据集或者设定了最大深度的情况下，会加速训练过程。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 决策树调参"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入库\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.tree import DecisionTreeRegressor\n",
    "from sklearn import metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(150, 4) (150,)\n"
     ]
    }
   ],
   "source": [
    "# 导入数据集\n",
    "X = datasets.load_iris()  # 以全部字典形式返回,有data,target,target_names三个键\n",
    "data = X.data\n",
    "target = X.target\n",
    "name = X.target_names\n",
    "x, y = datasets.load_iris(return_X_y=True)  # 能一次性取前2个\n",
    "print(x.shape, y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据分为训练集和测试集\n",
    "x_train, x_test, y_train, y_test = train_test_split(x,\n",
    "                                                    y,\n",
    "                                                    test_size=0.2,\n",
    "                                                    random_state=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最优分类器: {'criterion': 'gini', 'max_depth': 50, 'min_impurity_decrease': 0.1, 'min_samples_leaf': 5} 最优分数: 0.9416666666666665\n"
     ]
    }
   ],
   "source": [
    "# 用GridSearchCV寻找最优参数（字典）\n",
    "param = {\n",
    "    'criterion': ['gini'],\n",
    "    'max_depth': [30, 50, 60, 100],\n",
    "    'min_samples_leaf': [2, 3, 5, 10],\n",
    "    'min_impurity_decrease': [0.1, 0.2, 0.5]\n",
    "}\n",
    "grid = GridSearchCV(DecisionTreeClassifier(), param_grid=param, cv=6)\n",
    "grid.fit(x_train, y_train)\n",
    "print('最优分类器:', grid.best_params_, '最优分数:', grid.best_score_)  # 得到最优的参数和分值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 参考\n",
    "\n",
    "- https://github.com/fengdu78/lihang-code\n",
    "\n",
    "- 李航. 统计学习方法[M]. 北京: 清华大学出版社,2019.\n",
    "\n",
    "- https://scikit-learn.org"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
